#ifndef DYNOBJECTFACTORY_H
#define DYNOBJECTFACTORY_H
#include <map>
#include <QString>

using namespace std;

typedef void *(*CREATE_FUNC)();

class DynObjectFactory
{
public:
    static void *createObject(const QString& name)
    {
        map<QString,CREATE_FUNC>::const_iterator it;
        it = mapCls_.find(name);
        if(it == mapCls_.end()) {
            return NULL;
        } else {
            return it->second();
        }
    }

    static void registerObject(const QString &name,CREATE_FUNC func)
    {
        //首次插入操作前最好是调用下clear()方法，否则会出现莫名其妙的崩溃情况。
        if(firstUse_) {
            mapCls_.clear();
            firstUse_ = false;
        }
        mapCls_.insert(make_pair(name,func));
    }
private:
    static map<QString,CREATE_FUNC> mapCls_;
    static bool firstUse_;
};

template <typename T>
class DelegatingClass
{
public:
    DelegatingClass(const QString &name)
    {
        DynObjectFactory::registerObject(name,DelegatingClass::newInstance);
    }

    static void *newInstance()
    {
        return new T;
    }
};

#define REGISTER_CLASS(class_name)  static DelegatingClass<class_name> class##class_name(#class_name)

#endif // DYNOBJECTFACTORY_H
